﻿using System;
using System.Collections.Concurrent;

namespace FxSuperCore.Event
{
	public abstract class FxEvent<T> where T : Delegate
	{
		// 事件表
		protected ConcurrentDictionary<string, T> eventDic = new ConcurrentDictionary<string, T>();

		// 锁
		private readonly object locker = new object();

		// 注册第一个事件
		protected event Action OnRegisterFirstEvent;

		// 移除最后一个事件
		protected event Action OnUnRegisterLastEvent;


		protected string RegisterEvent(T e)
		{
			if (e == null)
			{
				throw new NullReferenceException("待注册的事件不可为null");
			}

			string id = Guid.NewGuid().ToString("N");
			lock (locker)
			{
				bool isEmpty = eventDic.IsEmpty;
				if (eventDic.TryAdd(id, e))
				{
					if (isEmpty)
					{
						OnRegisterFirstEvent?.Invoke();
					}
					return id;
				}
			}

			return null;
		}

		protected bool UnRegisterEvent(string eventId)
		{
			T e;
			lock (locker)
			{
				int srcCount = eventDic.Count;
				bool res = eventDic.TryRemove(eventId, out e);
				if (srcCount > 0 && eventDic.Count <= 0)
				{
					OnUnRegisterLastEvent?.Invoke();
				}
				return res;
			}
		}
	}
}
